package com.dgut.lab.security.filter;


import com.dgut.lab.security.DgutOAuth2AuthenticationProvider;
import com.dgut.lab.security.DgutOAuth2LoginAuthenticationToken;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Objects;

public class DgutOAuth2LoginAuthenticationFilter extends OncePerRequestFilter {
    private DgutOAuth2AuthenticationProvider dgutOAuth2AuthenticationProvider;

    private static final String DEFAULT_CALLBACK_BASE_URI = "/login/dgut";
    private static final String DEFAULT_LOGIN_SUCCESS_REDIRECT_URL = "/submit";
    private ProviderManager providerManager;

    public DgutOAuth2LoginAuthenticationFilter(AuthenticationProvider dgutOAuth2AuthenticationProvider) {
        this.dgutOAuth2AuthenticationProvider = (DgutOAuth2AuthenticationProvider) dgutOAuth2AuthenticationProvider;
        this.providerManager = new ProviderManager(Collections.singletonList((dgutOAuth2AuthenticationProvider)));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getParameter("token");
        if (!request.getRequestURI().endsWith(DEFAULT_CALLBACK_BASE_URI) || !StringUtils.hasText(token)) {
            filterChain.doFilter(request, response);
            return;
        }
        DgutOAuth2LoginAuthenticationToken dgutOAuth2LoginAuthenticationToken = new DgutOAuth2LoginAuthenticationToken(token,request);
        Authentication successAuthentication;
        try{
            successAuthentication =providerManager.authenticate(dgutOAuth2LoginAuthenticationToken);
        }catch (AuthenticationException e){
            // 如果校验失败providerManager会抛异常，在catch里作异常处理。
            // do somethings.
            return;
        }
        // 校验成功，执行后面的流程：
        SecurityContextHolder.getContext().setAuthentication(successAuthentication);
        request.getSession().removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        // 成功登录后，设置重定向到页面。
        redirectStrategy(request,response);
    }






    private void redirectStrategy(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String redirectUrl = DEFAULT_LOGIN_SUCCESS_REDIRECT_URL;
        SavedRequest savedRequest = (SavedRequest) request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST");
        if (Objects.nonNull(savedRequest))
            redirectUrl = savedRequest.getRedirectUrl();
        new DefaultRedirectStrategy().sendRedirect(request, response, redirectUrl);
    }




}
